package com.linkdood.app.utils;

import com.linkdood.app.service.ddio.TemplateMessage;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.security.cert.X509Certificate;

/**
 * Http 工具类
 * @author YunJ
 */
public class HttpUtil {

    private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);

    private static final String HTTPS_PREFIX = "https";

    public static ResponseEntity<String> getRestTemplate(String url) {
        RestTemplate restTemplate = restTemplate(url);
        return restTemplate.getForEntity(url, String.class);
    }

    public static ResponseEntity<String> getRestTemplate(String url, HttpHeaders headers) {
        RestTemplate restTemplate = restTemplate(url);
        RequestEntity<?> requestEntity = new RequestEntity<>(headers, HttpMethod.GET, URI.create(url));
        return restTemplate.exchange(requestEntity, String.class);
    }

    public static ResponseEntity<String> postRestTemplate(String url) {
        RestTemplate restTemplate = restTemplate(url);
        RequestEntity<?> requestEntity = new RequestEntity<>(HttpMethod.POST, URI.create(url));
        return restTemplate.exchange(requestEntity, String.class);
    }

    public static ResponseEntity<String> postRestTemplate(String url, Object body, HttpHeaders headers) {
        logger.debug("postRestTemplate body : {}", body.toString());
        RestTemplate restTemplate = restTemplate(url);
        RequestEntity<?> requestEntity = new RequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));
        return restTemplate.exchange(requestEntity, String.class);
    }

    public static ResponseEntity<String> postRestTemplate(String url, HttpHeaders headers) {
        RestTemplate restTemplate = restTemplate(url);
        RequestEntity<?> requestEntity = new RequestEntity<>(headers, HttpMethod.POST, URI.create(url));
        return restTemplate.exchange(requestEntity, String.class);
    }

    public static ResponseEntity<String> postTemplateMessage(String url, TemplateMessage templateMessage, HttpHeaders headers) {
        RestTemplate restTemplate = restTemplate(url);
        RequestEntity<?> requestEntity = new RequestEntity<>(templateMessage, headers, HttpMethod.POST, URI.create(url));
        return restTemplate.exchange(requestEntity, String.class);
    }

    public static RestTemplate restTemplate(String url) {
        RestTemplate restTemplate = new RestTemplate();
        if (url.startsWith(HTTPS_PREFIX)) {
            try {
                // 设置忽略 ssl 证书
                TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
                SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
                SSLConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
                CloseableHttpClient closeableHttpClient = HttpClients.custom().setSSLSocketFactory(connectionSocketFactory).build();
                HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
                requestFactory.setHttpClient(closeableHttpClient);
                requestFactory.setConnectTimeout(15000);
                requestFactory.setReadTimeout(5000);
                restTemplate = new RestTemplate(requestFactory);
            } catch (Exception e) {
                logger.error("get https restTemplate failed : {}", e.getMessage());
            }
        }
        return restTemplate;
    }

    public static String urlEncode(String str) {
        if (StringUtils.isEmpty(str)) {
            return str;
        }
        try {
            return URLEncoder.encode(str, "utf8");
        } catch (UnsupportedEncodingException e) {
            logger.error("{}", e.getMessage());
            return str;
        }
    }
}
